home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmiSoft / Disk / moni / FileX-src.lha / FileX-src / search.c < prev    next >
C/C++ Source or Header  |  2003-11-09  |  23KB  |  1,041 lines

  1. #include "FileXStructs.h"
  2. #include "FileXStrings.h"
  3.  
  4. #include "allprotos.h"
  5.  
  6. char searchstring[256];                    /* ASCII-Text-Suchstring */
  7. static char hexsearchstring[128];    /* Hex-Suchbytes */
  8.  
  9. char replacestring[256];
  10. static char hexreplacestring[128];
  11.  
  12. long searchmode = SM_STRING;
  13.  
  14. static struct Speicher ReplaceSpeicher;
  15. static LONG delta[256];
  16.  
  17. static struct List SHList = {
  18.     ( struct Node * )&SHList.lh_Tail,
  19.     0,
  20.     ( struct Node * )&SHList.lh_Head,
  21.     0,0
  22. };
  23.  
  24. static struct List RHList = {
  25.     ( struct Node * )&RHList.lh_Tail,
  26.     0,
  27.     ( struct Node * )&RHList.lh_Head,
  28.     0,0
  29. };
  30.  
  31. static struct Node *SHAktu;
  32. static struct Node *RHAktu;
  33.  
  34. void FreeSearchHistory( void )
  35. {
  36.     while( !IsListEmpty( &SHList ))
  37.         FreeNLNode( SHList.lh_Head );
  38.  
  39.     while( !IsListEmpty( &RHList ))
  40.         FreeNLNode( RHList.lh_Head );
  41. }
  42.  
  43. void InitSearchHistory( void )
  44. {
  45. }
  46.  
  47. /*
  48.  * static long CountSpecChars(UBYTE *string,char zeichen)
  49.  *
  50.  * Ermittelt die Anzahl von einem bestimmten Zeichen in einem String
  51.  */
  52.  
  53. static long CountSpecChars(UBYTE *string,char zeichen)
  54. {
  55.     long num=0;
  56.  
  57.     while( *string != 0) if( *string++ == zeichen) num++;
  58.  
  59.     return( num );
  60. }
  61.  
  62. /*
  63.  * static void Replace(long pos,UBYTE *quelle,long len)
  64.  *
  65.  * Ersetzt einen Text an pos mit der Länge len durch den ab Quelle
  66.  * und ändert auch den Text im Anzeigebereich falls nötig
  67.  */
  68.  
  69. static void Replace(long pos,UBYTE *quelle,long len, struct DisplayData *DD)
  70. {
  71.     struct Speicher s, rs;
  72.     s.len = len;
  73.  
  74.     if(s.mem = AllocMem(s.len,MEMF_ANY))
  75.     {
  76.         rs.len = ReplaceSpeicher.len;
  77.  
  78.         if( rs.mem = AllocMem( rs.len, MEMF_ANY ))
  79.         {
  80.             memcpy( rs.mem, ReplaceSpeicher.mem, rs.len );
  81.  
  82.             AddUndoPaste(pos, s, rs,DD->FD);
  83.  
  84.                 /* Sichern */
  85.  
  86.             memcpy(s.mem,DD->FD->Mem+pos,len);
  87.  
  88.                 /* String drüber */
  89.  
  90.             memcpy(DD->FD->Mem+pos,quelle,len);
  91.     
  92.             AllDisplay( DD->FD, SCROLLERNEU);
  93.         }
  94.         else
  95.             FreeMem( s.mem, s.len );
  96.     }
  97. }
  98.  
  99. /*
  100.  * int TestHexString(char *s)
  101.  *
  102.  * Liefert Anzahl Bytes, falls s ein gültiger Hexstring ist = nur '0'-'9',
  103.  * ' ','A-F','a-f'. Oder -1 falls üngültige Zeichen enthalten sind.
  104.  */
  105.  
  106. int TestHexString(char *s)
  107. {
  108.     int anz=0;
  109.     char *starts=s;
  110.  
  111.     while(*s!=0)
  112.     {
  113.         if(isxdigit(*s))    anz++;
  114.         else if(!(*s==' '))
  115.         {
  116.             MyRequest( MSG_INFO_GLOBAL_ILLEGALCHARACTERS, ( ULONG )starts );
  117.             return(-1);
  118.         }
  119.         s++;
  120.     }
  121.     if(anz%2!=0)
  122.     {
  123.         MyRequest( MSG_INFO_GLOBAL_HEXSTRINGNICHTBYTEALIGNED, ( ULONG )starts );
  124.         return(-1);
  125.     }
  126.     else    return(anz);
  127. }
  128.  
  129. static long memcmpwild(UBYTE *wild,UBYTE *string,long laenge)
  130. {
  131.     long k;
  132.  
  133.     for(k=0;k<laenge;k++)if((!(wild[k]==WILDCHAR))&&(string[k]!=wild[k]))return(-1);
  134.     
  135.     return(0);
  136. }
  137.  
  138. static long strnicmpwild(UBYTE *wild,UBYTE *string,long laenge)
  139. {
  140.     long k;
  141.  
  142.     for(k=0;k<laenge;k++)if((!(wild[k]==WILDCHAR))&&(ToUpper(string[k])!=ToUpper(wild[k])))return(-1);
  143.     
  144.     return(0);
  145. }
  146.  
  147. /*
  148.  * UBYTE *BoyerMoore(UBYTE *start,UBYTE *ss,ULONG typ)
  149.  *
  150.  * Sucht ab start und gibt Zeiger auf gefundenes zurück
  151.  * ss=Zeiger auf zu suchenden String
  152.  */
  153.  
  154. static UBYTE *BoyerMoore(UBYTE *start,UBYTE *ss,ULONG typ,LONG len, struct DisplayData *DD )
  155. {
  156.     UBYTE *t;
  157.  
  158.     if(DD->FD->Len==0)return(NULL);
  159.  
  160.     if(typ&BM_BACKWARD)
  161.     {
  162.             /* Falls wir zu weit hinten stehen, auf erste pos setzen */
  163.         if(len>DD->FD->Len-(start-DD->FD->Mem))start=DD->FD->Len+DD->FD->Mem-len;
  164.  
  165.             /* Falls wir nun außerhalb sind */
  166.         if(start<=DD->FD->Mem)return(NULL);
  167.  
  168.         len--;
  169.         t = start;
  170.  
  171.         if(typ&BM_WILDCARDS)
  172.         {
  173.             if(typ&BM_CASE)
  174.             while(t>=DD->FD->Mem)
  175.             {
  176.                 if(((*ss==WILDCHAR)||(*ss == *t))    &&
  177.                     (memcmpwild(ss+1,t+1,len) == 0))
  178.                         return(t);
  179.     
  180.                 t-=delta[*t];
  181.             }
  182.             else
  183.             while(t>=DD->FD->Mem)
  184.             {
  185.                 if(((*ss==WILDCHAR)||(ToUpper(*ss) == ToUpper(*t)))
  186.                     &&(strnicmpwild(ss+1,t+1,len) == 0))
  187.                         return(t);
  188.     
  189.                 t-=delta[*t];
  190.             }
  191.         }
  192.         else
  193.         {
  194.             if(typ&BM_CASE)
  195.             while(t>=DD->FD->Mem)
  196.             {
  197.                 if((*ss == *t)    &&
  198.                     (memcmp(ss+1,t+1,len) == 0))
  199.                         return(t);
  200.     
  201.                 t-=delta[*t];
  202.             }
  203.             else
  204.             while(t>=DD->FD->Mem)
  205.             {
  206.                 if((ToUpper(*ss) == ToUpper(*t))
  207.                     &&(strnicmp(ss+1,t+1,len) == 0))
  208.                         return(t);
  209.     
  210.                 t-=delta[*t];
  211.             }
  212.         }
  213.     }
  214.     else
  215.     {
  216.         UBYTE *zfende;
  217.  
  218.         if(len>DD->FD->Len+DD->FD->Mem-start)return(NULL);
  219.  
  220.         len--;
  221.         zfende=ss+len;
  222.         t = start + len;
  223.  
  224.         if(typ&BM_WILDCARDS)
  225.         {
  226.             if(typ&BM_CASE)
  227.             while(t<DD->FD->Mem+DD->FD->Len)
  228.             {
  229.                 if(((*zfende==WILDCHAR)||(*zfende == *t))&&
  230.                     (memcmpwild(zfende-len,t-len,len)==0))
  231.                         return(t - len);
  232.     
  233.                 t+=delta[*t];
  234.             }
  235.             else
  236.             while(t<DD->FD->Mem+DD->FD->Len)
  237.             {
  238.                 if(((*zfende==WILDCHAR)||(ToUpper(*zfende)== ToUpper(*t)))&&
  239.                     (strnicmpwild(zfende-len,t-len,len) == 0))
  240.                         return(t - len);
  241.     
  242.                 t+=delta[*t];
  243.             }
  244.         }
  245.         else
  246.         {
  247.             if(typ&BM_CASE)
  248.             while(t<DD->FD->Mem+DD->FD->Len)
  249.             {
  250.                 if((*zfende == *t)&&
  251.                     (memcmp(zfende-len,t-len,len)==0))
  252.                         return(t - len);
  253.     
  254.                 t+=delta[*t];
  255.             }
  256.             else
  257.             while(t<DD->FD->Mem+DD->FD->Len)
  258.             {
  259.                 if((ToUpper(*zfende)== ToUpper(*t))&&
  260.                     (strnicmp(zfende-len,t-len,len) == 0))
  261.                         return(t - len);
  262.     
  263.                 t+=delta[*t];
  264.             }
  265.         }
  266.     }
  267.     return(NULL);
  268. }
  269.  
  270. /*
  271.  * static void InitBM(UBYTE *ss,ULONG typ,ULONG len)
  272.  *
  273.  * Baut die Deltatabelle für den BoyerMooreAlgorithmus auf
  274.  * ss  = zu suchender String
  275.  * typ = Suchart (CASE/BACK)
  276.  */
  277.  
  278. static void InitBM( UBYTE *ss, ULONG typ, ULONG len )
  279. {
  280.     unsigned char *zf;
  281.     LONG i;
  282.  
  283.         /* Deltas berechnen */
  284.     for( i = 0; i < 256; i++ )
  285.         delta[ i ] = len;
  286.  
  287.     if( typ & BM_CASE )
  288.     {
  289.         if(typ&BM_BACKWARD)    for(zf=ss,i=len-1;i>0;--i)    delta[zf[i]]=i;
  290.         else    for(i=len,zf=ss; --i > 0;)    delta[*zf++] = i;
  291.     }
  292.     else
  293.     {
  294.         if(typ&BM_BACKWARD)
  295.         {
  296.             for(zf=ss,i=len-1;i>0;--i)    delta[ToUpper(zf[i])]=i;
  297.             for(i=0;i<256;i++)delta[tolower(i)]=delta[i];
  298.         }
  299.         else
  300.         {
  301.             for(i=len,zf=ss; --i > 0;)
  302.             {
  303.                 UBYTE dummy;
  304.                 dummy=*zf++;
  305.                 delta[ToUpper(dummy)]=i;
  306.             }
  307.             for(i=0;i<256;i++)delta[tolower(i)]=delta[i];
  308.         }
  309.     }
  310.  
  311.     if( typ & BM_WILDCARDS )
  312.     {
  313.         if( typ & BM_BACKWARD )
  314.         {
  315.             long pos = 0;
  316.     
  317.             for( zf = ss; zf < ss + len; pos ++ )
  318.             {
  319.                 if( *zf++ == WILDCHAR )
  320.                     break;
  321.             }
  322.  
  323.             if( !pos )
  324.                 pos = 1;
  325.     
  326.             for( i = 0; i < 256; i++ )
  327.                 if( delta[ i ] > pos )
  328.                     delta[ i ] = pos;
  329.         }
  330.         else
  331.         {
  332.             long pos = 0;
  333.     
  334.             for( zf = ss + len - 1; zf >= ss; pos ++ )
  335.                 if( *zf-- == WILDCHAR )
  336.                     break;
  337.     
  338.             if( !pos )
  339.                 pos = 1;
  340.  
  341.             for( i = 0; i < 256; i++ )
  342.                 if( delta[ i ] > pos )
  343.                     delta[ i ] = pos;
  344.         }
  345.     }
  346. }
  347.  
  348. BOOL SearchNext(int typ,BOOL quiet,BOOL all, struct DisplayData *DD )
  349. {
  350.     UBYTE *pos;
  351.     char *string;
  352.     LONG len;
  353.     BOOL Success = TRUE;
  354.     struct Window *SWnd;
  355.  
  356.     SWnd = AktuDI->Wnd;
  357.  
  358.     SetStatusZeile( GetStr( MSG_INFO_SEARCH_SEARCHING ), DD);
  359.  
  360.     if(searchmode&SM_REPLACE)
  361.     {
  362.         char *rstring,*kstring,*krstring;
  363.         long richtung=(typ&BM_BACKWARD)?-1:1;
  364.  
  365.         if( !(searchmode&SM_STRING))
  366.         {
  367.             int hexsearchbytes, hexreplacebytes;
  368.  
  369.             typ|=BM_CASE;
  370.  
  371.             if((-1!=(hexsearchbytes =TestHexString(searchstring)))&&
  372.                 (-1!=(hexreplacebytes=TestHexString(replacestring))))
  373.             {
  374.                 if(hexsearchbytes == hexreplacebytes)
  375.                 {
  376.                     len = ConvertHexstringToHexnumber(kstring=searchstring,string=hexsearchstring);
  377.                     ConvertHexstringToHexnumber(krstring=replacestring,rstring=hexreplacestring);
  378.                 }
  379.                 else
  380.                 {
  381.                     DisplayLocaleText( MSG_INFO_SEARCH_BYTESNOTEQUAL );
  382.                     Success = FALSE;
  383.                 }
  384.             }
  385.             else
  386.                 Success = FALSE;
  387.         }
  388.         else
  389.         {
  390.             if(searchmode&SM_WILDCARDS)
  391.             {
  392.                 if(CountSpecChars(searchstring,WILDCHAR))typ|=BM_WILDCARDS;
  393.             }
  394.  
  395.             if(!(strlen(krstring=rstring=replacestring)==(len=strlen(kstring=string=searchstring))))
  396.             {
  397.                 DisplayLocaleText( MSG_INFO_SEARCH_CHARSNOTEQUAL );
  398.                 Success = FALSE;
  399.             }
  400.  
  401.             if(searchmode&SM_CASE)typ|=BM_CASE;
  402.         }
  403.  
  404.         if(len && Success)
  405.         {
  406.             ReplaceSpeicher.len = len;
  407.  
  408.             if(ReplaceSpeicher.mem = AllocMem(len,MEMF_ANY))
  409.             {
  410.                 char fstring[256], *fstringzeiger;
  411.                 
  412.                 fstring[len]=0;
  413.                 fstringzeiger = fstring;
  414.  
  415.                 memcpy(ReplaceSpeicher.mem,rstring,len);
  416.  
  417.                 InitBM(string,typ,len);
  418.     
  419.                 if(all)
  420.                 {
  421.                     SetWaitPointer( SWnd );
  422.                     if(pos=BoyerMoore(DD->FD->Mem+DD->CPos,string,typ,len, DD))
  423.                     {
  424.                         Replace(pos-DD->FD->Mem,rstring,len,DD);
  425.                         while(pos=BoyerMoore(pos+richtung,string,typ,len,DD))
  426.                             Replace(pos-DD->FD->Mem,rstring,len,DD);
  427.                     }
  428.                     ClrWaitPointer( SWnd );
  429.  
  430.                     Success=TRUE;
  431.                 }
  432.                 else        
  433.                 if(quiet)
  434.                 {
  435.                     if(pos=BoyerMoore(DD->FD->Mem+DD->CPos,string,typ,len,DD))
  436.                     {
  437.                         Replace(pos-DD->FD->Mem,rstring,len,DD);
  438.                         Success=TRUE;
  439.                     }
  440.                     else
  441.                     {
  442.                         Success=FALSE;
  443.                     }
  444.                 }
  445.                 else
  446.                 {
  447.                     BOOL all=FALSE,EndeFlag=FALSE;
  448.     
  449.                     SetWaitPointer( SWnd );
  450.  
  451.                     if(pos=BoyerMoore(DD->FD->Mem+DD->CPos,string,typ,len,DD))
  452.                     do
  453.                     {
  454.                         Success=TRUE;
  455.                         ClrWaitPointer( SWnd );
  456.     
  457.                         if(( searchmode & SM_STRING ) && ( searchmode & SM_WILDCARDS ))
  458.                             strncpy(fstring,pos,len);
  459.                         else
  460.                         {
  461.                             fstringzeiger = searchstring;
  462.                         }
  463.     
  464.                         SetCursor(pos-DD->FD->Mem, DD);
  465.                         switch(MyFullRequest( MSG_INFO_SEARCH_FOUNDTOREPLACE, MSG_GADGET_REPLACE, fstringzeiger, krstring ))
  466.                         {
  467.                             case 1:
  468.                                 Replace(pos-DD->FD->Mem,rstring,len,DD);
  469.                                 break;
  470.                             case 2:
  471.                                 Replace(pos-DD->FD->Mem,rstring,len,DD);
  472.                                 all=TRUE;
  473.                                 SetWaitPointer( SWnd );
  474.                                 while(pos=BoyerMoore(pos+richtung,string,typ,len,DD))
  475.                                     Replace(pos-DD->FD->Mem,rstring,len,DD);
  476.                                 ClrWaitPointer( SWnd );
  477.                                 EndeFlag=TRUE;
  478.                                 break;
  479.                             case 3:
  480.                                 Replace(pos-DD->FD->Mem,rstring,len,DD);
  481.                                 EndeFlag=TRUE;
  482.                                 break;
  483.                             case 4:
  484.                                 EndeFlag=TRUE;
  485.                                 break;
  486.                         }
  487.         
  488.                         SetWaitPointer( SWnd );
  489.         
  490.                     }while((!EndeFlag)&&(pos=BoyerMoore(pos+richtung,string,typ,len,DD)));
  491.                     else Success=FALSE;
  492.         
  493.                     ClrWaitPointer( SWnd );
  494.         
  495.                     if((all==FALSE)&&(EndeFlag==FALSE))
  496.                     {
  497.                         if(!quiet)
  498.                             MyRequest( MSG_INFO_SEARCH_STRINGNOTFOUND, ( ULONG )searchstring );
  499.                     }
  500.                 }
  501.  
  502.                 FreeMem( ReplaceSpeicher.mem, ReplaceSpeicher.len );
  503.             }
  504.             else
  505.                 MyRequest( MSG_INFO_GLOBAL_CANTALLOCMEM, len );
  506.         }
  507.     }
  508.     else
  509.     {
  510.         if(!(searchmode&SM_STRING))
  511.         {
  512.             if(-1!=TestHexString(searchstring))
  513.             {
  514.                 len=ConvertHexstringToHexnumber(searchstring,hexsearchstring);
  515.                 string=hexsearchstring;
  516.                 typ|=BM_CASE;
  517.             }
  518.             else
  519.                 Success = FALSE;
  520.         }
  521.         else
  522.         {
  523.             if(searchmode&SM_WILDCARDS)
  524.             {
  525.                 if(CountSpecChars(searchstring,WILDCHAR))typ|=BM_WILDCARDS;
  526.             }
  527.  
  528.             len=strlen(string=searchstring);
  529.             if(searchmode&SM_CASE)typ|=BM_CASE;
  530.         }
  531.  
  532.         if(Success && len)
  533.         {
  534.             InitBM(string,typ,len);
  535.             SetWaitPointer( SWnd );
  536.             pos=BoyerMoore(DD->FD->Mem+DD->CPos+((typ&BM_BACKWARD)?-1:1),string,typ,len,DD);
  537.             ClrWaitPointer( SWnd );
  538.  
  539.             if(pos)
  540.             {
  541.                 SetCursor(pos-DD->FD->Mem, DD);
  542.                 Success=TRUE;
  543.             }
  544.             else
  545.             {
  546.                 if(!quiet)
  547.                 if(searchmode&SM_STRING)MyRequest( MSG_INFO_SEARCH_STRINGNOTFOUND, ( ULONG )searchstring );
  548.                 else MyRequest( MSG_INFO_SEARCH_STRINGNOTFOUND, ( ULONG )searchstring );
  549.  
  550.                 Success=FALSE;
  551.             }
  552.         }
  553.     }
  554.  
  555.     UpdateStatusZeile(DD);
  556.     SetScrollerGadget(DD);
  557.  
  558.     return(Success);
  559. }
  560.  
  561. void SetSearchString( char *string )
  562. {
  563.     strcpy( searchstring, string );
  564.  
  565.     if( strlen( string ))
  566.     if( IsListEmpty( &SHList ) || strcmp( string, SHList.lh_TailPred->ln_Name ))
  567.         AddNLName( &SHList, string );
  568. }
  569.  
  570. void SetReplaceString( char *string )
  571. {
  572.     strcpy( replacestring, string );
  573.  
  574.     if( strlen( string ))
  575.     if( IsListEmpty( &RHList ) || strcmp( string, RHList.lh_TailPred->ln_Name ))
  576.         AddNLName( &RHList, string );
  577. }
  578.  
  579. char *GetAktuSearchString( void )
  580. {
  581.     return( searchstring );
  582. }
  583.  
  584. char *GetAktuReplaceString( void )
  585. {
  586.     return( replacestring );
  587. }
  588.  
  589. /****************************** SearchWindow ******************************/
  590.  
  591. enum {
  592.  
  593. GD_SEARCH_SEARCHSTRING,
  594. GD_SEARCH_REPLACESTRING,
  595.  
  596. GD_SEARCH_CASESENSITIV,
  597. GD_SEARCH_WILDCARDS,
  598. GD_SEARCH_STRINGSEARCH,
  599. GD_SEARCH_REPLACEMODE,
  600.  
  601. GD_SEARCH_NEXT,
  602. GD_SEARCH_PREVIOUS,
  603. GD_SEARCH_CANCEL
  604. };
  605.  
  606. static struct MyNewGadget SearchNewGadgets[] =
  607. {
  608.     STRING_KIND, 0, 0, 0, MSG_GADGET_SEARCH_SEARCHSTRING, 0, 256, 0, 30, 30,
  609.     STRING_KIND, 0, 0, 0, MSG_GADGET_SEARCH_REPLACESTRING, 0, 256, 0, 30, 30,
  610.  
  611.     CHECKBOX_KIND, GP_NEWCOLUMN, 0, 0, MSG_GADGET_SEARCH_CASESENSITIV, 0, 0, 0, 0, 0,
  612.     CHECKBOX_KIND, 0, 0, 0, MSG_GADGET_SEARCH_WILDCARDS, 0, 0, 0, 0, 0,
  613.     CHECKBOX_KIND, 0, 0, 0, MSG_GADGET_SEARCH_STRINGSEARCH, 0, 0, 0, 0, 0,
  614.     CHECKBOX_KIND, 0, 0, 0, MSG_GADGET_SEARCH_REPLACEMODE, 0, 0, 0, 0, 0,
  615.  
  616.     BUTTON_KIND, GP_LEFTBOTTOM, 0, 0, MSG_GADGET_SEARCH_NEXT, 0, 0, 0, 0, 0,
  617.     BUTTON_KIND, GP_MIDDLEBOTTOM, 0, 0, MSG_GADGET_SEARCH_PREVIOUS, 0, 0, 0, 0, 0,
  618.     BUTTON_KIND, GP_RIGHTBOTTOM, 0, 0, MSG_GADGET_CANCEL, 0, 0, 0, 0, 0,
  619.     0
  620. };
  621.  
  622. static struct WindowData SearchWD =
  623. {
  624.     NULL,    NULL,    FALSE, NULL, NULL,
  625.     0,0,
  626.     &SearchNewGadgets[ 0 ], 9
  627. };
  628.  
  629. static void DoSearchWndMsg( void )
  630. {
  631.     struct IntuiMessage    *m, Msg;
  632.     struct Gadget *gad;
  633.     int Select = -1;    /* Wie wurde Window verlassen? (-1=Nicht/0=Cancel / Next / Previous) */
  634.  
  635.     while( m = GT_GetIMsg( SearchWD.Wnd->UserPort ))
  636.     {
  637.         CopyMem(( char * )m, ( char * )&Msg, (long)sizeof( struct IntuiMessage ));
  638.  
  639.         GT_ReplyIMsg( m );
  640.  
  641.         KeySelect( SearchWD.Gadgets, &Msg );
  642.  
  643.         gad = (struct Gadget *) Msg.IAddress;
  644.  
  645.         switch( Msg.Class )
  646.         {
  647. /*            case    IDCMP_REFRESHWINDOW:
  648.                 GT_BeginRefresh( SearchWD.Wnd );
  649.                 GT_EndRefresh( SearchWD.Wnd, TRUE );
  650.                 break;*/
  651.  
  652.             case    IDCMP_VANILLAKEY:
  653.                 if( Msg.Code == 13)
  654.                     Select = 1;
  655.                 break;
  656.  
  657.             case    IDCMP_CLOSEWINDOW:
  658.                 Select = 0;
  659.                 break;
  660.  
  661.             case    IDCMP_GADGETUP:
  662.                 switch(gad->GadgetID)
  663.                 {
  664.                     case GD_SEARCH_SEARCHSTRING:
  665.                         if( SearchNewGadgets[ GD_SEARCH_STRINGSEARCH ].CurrentValue == FALSE )
  666.                         {
  667.                             if(-1==TestHexString(GetString(SearchWD.Gadgets[GD_SEARCH_SEARCHSTRING])))
  668.                                 ActivateGadget(SearchWD.Gadgets[GD_SEARCH_SEARCHSTRING],SearchWD.Wnd,0);
  669.                             else
  670.                                 if( SearchNewGadgets[ GD_SEARCH_REPLACEMODE ].CurrentValue )
  671.                                     ActivateGadget( SearchWD.Gadgets[ GD_SEARCH_REPLACESTRING ], SearchWD.Wnd, 0 );
  672.                                 else
  673.                                     Select = 1;
  674.                         }
  675.                         else
  676.                         {
  677.                             if( SearchNewGadgets[ GD_SEARCH_REPLACEMODE ].CurrentValue )
  678.                                 ActivateGadget( SearchWD.Gadgets[ GD_SEARCH_REPLACESTRING ], SearchWD.Wnd, 0 );
  679.                             else
  680.                                 Select = 1;
  681.                         }
  682.                         break;
  683.  
  684.                     case GD_SEARCH_REPLACESTRING:
  685.                         if(( SearchNewGadgets[ GD_SEARCH_STRINGSEARCH ].CurrentValue == FALSE ) &&
  686.                             (-1==TestHexString(GetString(SearchWD.Gadgets[GD_SEARCH_SEARCHSTRING]))))
  687.                                 ActivateGadget(SearchWD.Gadgets[GD_SEARCH_REPLACESTRING],SearchWD.Wnd,0);
  688.                         else
  689.                             Select = 1;
  690.                         break;
  691.  
  692.                     case GD_SEARCH_REPLACEMODE:
  693.                         GT_SetGadgetAttrs( SearchWD.Gadgets[ GD_SEARCH_REPLACESTRING ], SearchWD.Wnd, NULL, GA_Disabled, ((struct MyNewGadget *)gad->UserData)->CurrentValue, TAG_DONE );
  694.                     case GD_SEARCH_CASESENSITIV:
  695.                     case GD_SEARCH_WILDCARDS:
  696.                     case GD_SEARCH_STRINGSEARCH:
  697.                         ((struct MyNewGadget *)gad->UserData)->CurrentValue = !((struct MyNewGadget *)gad->UserData)->CurrentValue;
  698.                         break;
  699.  
  700.                     case GD_SEARCH_NEXT:
  701.                         Select = 1;
  702.                         break;
  703.  
  704.                     case GD_SEARCH_PREVIOUS:
  705.                         Select = 2;
  706.                         break;
  707.  
  708.                     case GD_SEARCH_CANCEL:
  709.                         Select = 0;
  710.                         break;
  711.                 }
  712.                 break;
  713.         }
  714.     }
  715.  
  716.  
  717.     if( Select > 0 )        /* Next/Previous -> Werte merken */
  718.     {
  719.         SetSearchString( GetString( SearchWD.Gadgets[ GD_SEARCH_SEARCHSTRING ] ));
  720.         SetReplaceString( GetString( SearchWD.Gadgets[ GD_SEARCH_REPLACESTRING ] ));
  721.  
  722.         searchmode &= ~( SM_CASE | SM_STRING | SM_WILDCARDS | SM_REPLACE );
  723.  
  724.         if( SearchNewGadgets[ GD_SEARCH_CASESENSITIV ].CurrentValue )
  725.             searchmode |= SM_CASE;
  726.  
  727.         if( SearchNewGadgets[ GD_SEARCH_WILDCARDS ].CurrentValue )
  728.             searchmode |= SM_WILDCARDS;
  729.  
  730.         if( SearchNewGadgets[ GD_SEARCH_STRINGSEARCH ].CurrentValue )
  731.             searchmode |= SM_STRING;
  732.  
  733.         if( SearchNewGadgets[ GD_SEARCH_REPLACEMODE ].CurrentValue )
  734.             searchmode |= SM_REPLACE;
  735.     }
  736.  
  737.     if( Select != -1 )
  738.     {
  739.         MyRemoveSignal( 1L << SearchWD.Wnd->UserPort->mp_SigBit );
  740.         NewCloseAWindow( &SearchWD );
  741.     }
  742.     
  743.     switch( Select )
  744.     {
  745.         case 1:
  746.             SearchNext(0, FALSE, FALSE,AktuDD);
  747.             break;
  748.  
  749.         case 2:
  750.             SearchNext(BM_BACKWARD, FALSE, FALSE,AktuDD);
  751.             break;
  752.     }
  753. }
  754.  
  755. void SendMsg( struct Window * w, UBYTE Key )
  756. {
  757.     struct IntuiMessage *Msg;
  758.  
  759.     if( Msg = AllocVec( sizeof( struct ExtIntuiMessage ), MEMF_CLEAR ))
  760.     {
  761.         Msg->ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
  762.         Msg->ExecMessage.mn_Length = sizeof( struct IntuiMessage );
  763.         Msg->ExecMessage.mn_ReplyPort = GadgetReplyPort;
  764.  
  765.         Msg->Class = IDCMP_VANILLAKEY;
  766.         Msg->Code = (UWORD)Key;
  767.         Msg->Qualifier = 0;
  768.         Msg->IAddress = NULL;
  769.         Msg->IDCMPWindow = w;
  770.  
  771.         PutMsg( w->UserPort, ( struct Message * )Msg );
  772.     }
  773. }
  774.  
  775. static ULONG __saveds __asm SearchHookFunc(    register __a0 struct Hook *hook,
  776.                                                         register __a2 struct SGWork *sgw,
  777.                                                         register __a1 unsigned long *msg    )
  778. {
  779.     struct InputEvent *ie;
  780.     ULONG return_code = ~0;
  781.     static long ShiftSearchLaenge = -1;
  782.  
  783.     if( *msg == SGH_KEY )
  784.     {
  785.         ie = sgw->IEvent;
  786.  
  787.         if( ie->ie_Class == IECLASS_RAWKEY )
  788.         {
  789.             if(( ie->ie_Qualifier & IEQUALIFIER_RCOMMAND ) && ( sgw->EditOp == EO_INSERTCHAR ))
  790.             {
  791.                 UBYTE Buffer[10];
  792.  
  793.                 if( 1 == MapRawKey(ie, Buffer, 10, 0))
  794.                 {
  795.                     SendMsg( sgw->GadgetInfo->gi_Window,Buffer[0] );
  796.                     sgw->Actions = 0;
  797.                 }
  798.             }
  799.             else
  800.             if( SearchWD.Wnd && (sgw->GadgetInfo->gi_Window == SearchWD.Wnd ))
  801.             {
  802.                 struct Node *HAktu;
  803.                 struct List *HList;
  804.  
  805.                 if( sgw->Gadget == SearchWD.Gadgets[ GD_SEARCH_SEARCHSTRING ])
  806.                 {
  807.                     HAktu = SHAktu;
  808.                     HList = &SHList;
  809.                 }
  810.                 else
  811.                 {
  812.                     HAktu = RHAktu;
  813.                     HList = &RHList;
  814.                 }
  815.  
  816.                 if( sgw->EditOp != EO_NOOP )
  817.                 {
  818.                     ShiftSearchLaenge = -1;
  819.                 }
  820.                 else
  821.                 if( ie->ie_Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ))
  822.                 {
  823.                     struct Node *node;
  824.  
  825.                     if(( ie->ie_Code == CURSORUP ) || ( ie->ie_Code == CURSORDOWN ))
  826.                     {
  827.                         if( ShiftSearchLaenge == -1 )
  828.                             ShiftSearchLaenge = strlen( sgw->WorkBuffer );
  829.  
  830.                         if( !IsListEmpty( HList ))
  831.                         {
  832.                             if( HAktu )
  833.                                 node = HAktu;
  834.                             else
  835.                                 node = HList->lh_TailPred;
  836.  
  837.                             if( ie->ie_Code == CURSORUP )
  838.                             {
  839.                                 if( !strcmp( node->ln_Name, sgw->WorkBuffer ))
  840.                                 {
  841.                                     node = node->ln_Pred;
  842.                                 }
  843.                             
  844.                                 if( node != ( struct Node * )HList )
  845.                                 while( strnicmp( sgw->WorkBuffer, node->ln_Name, ShiftSearchLaenge ))
  846.                                 {
  847.                                     node = node->ln_Pred;
  848.             
  849.                                     if( node == ( struct Node * )HList )
  850.                                         break;
  851.                                 }
  852.     
  853.                                 if( node == ( struct Node * )HList )
  854.                                 {
  855.                                     sgw->Actions = SGA_BEEP;
  856.                                 }
  857.                                 else
  858.                                 {
  859.                                     HAktu = node;
  860.                                     sgw->WorkBuffer = HAktu->ln_Name;
  861.                                     sgw->NumChars = strlen( HAktu->ln_Name );
  862.                                 }
  863.                             }
  864.                             else
  865.                             {
  866.                                 if( !strcmp( node->ln_Name, sgw->WorkBuffer ))
  867.                                 {
  868.                                     node = node->ln_Succ;
  869.                                 }
  870.                             
  871.                                 if( node != ( struct Node * )&HList->lh_Tail )
  872.                                 while( strnicmp( sgw->WorkBuffer, node->ln_Name, ShiftSearchLaenge ))
  873.                                 {
  874.                                     node = node->ln_Succ;
  875.             
  876.                                     if( node == ( struct Node * )&HList->lh_Tail )
  877.                                         break;
  878.                                 }
  879.     
  880.                                 if( node == ( struct Node * )&HList->lh_Tail )
  881.                                 {
  882.                                     sgw->Actions = SGA_BEEP;
  883.                                 }
  884.                                 else
  885.                                 {
  886.                                     HAktu = node;
  887.                                     sgw->WorkBuffer = HAktu->ln_Name;
  888.                                     sgw->NumChars = strlen( HAktu->ln_Name );
  889.                                 }
  890.                             }
  891.                         }
  892.                     }
  893.                 }
  894.                 else
  895.                 if( ie->ie_Qualifier & IEQUALIFIER_CONTROL )
  896.                 {
  897.                     switch( ie->ie_Code )
  898.                     {
  899.                         case CURSORUP:
  900.                             if( !IsListEmpty( HList ))
  901.                             {
  902.                                 HAktu = HList->lh_Head;
  903.                                 sgw->WorkBuffer = HAktu->ln_Name;
  904.                                 sgw->NumChars = strlen( HAktu->ln_Name );
  905.                             }
  906.                             break;
  907.     
  908.                         case CURSORDOWN:
  909.                             if( !IsListEmpty( HList ))
  910.                             {
  911.                                 HAktu = HList->lh_TailPred;
  912.                                 sgw->WorkBuffer = HAktu->ln_Name;
  913.                                 sgw->NumChars = strlen( HAktu->ln_Name );
  914.                             }
  915.                             break;
  916.                     }
  917.                 }
  918.                 else
  919.                 {
  920.                     ShiftSearchLaenge = -1;
  921.  
  922.                     switch( ie->ie_Code )
  923.                     {
  924.                         case CURSORUP:
  925.                             if( HAktu == 0 )
  926.                             {
  927.                                 if( !IsListEmpty( HList ))
  928.                                 {
  929.                                     HAktu = HList->lh_TailPred;
  930.                                     sgw->WorkBuffer = HAktu->ln_Name;
  931.                                     sgw->NumChars = strlen( HAktu->ln_Name );
  932.                                 }
  933.                             }
  934.                             else
  935.                             if( HAktu->ln_Pred != ( struct Node * )HList )
  936.                             {
  937.                                 HAktu = HAktu->ln_Pred;
  938.                                 sgw->WorkBuffer = HAktu->ln_Name;
  939.                                 sgw->NumChars = strlen( HAktu->ln_Name );
  940.                             }
  941.                             break;
  942.     
  943.                         case CURSORDOWN:
  944.                             if( HAktu != 0 )
  945.                             if( HAktu->ln_Succ != ( struct Node * )&HList->lh_Tail )
  946.                             {
  947.                                 HAktu = HAktu->ln_Succ;
  948.                                 sgw->WorkBuffer = HAktu->ln_Name;
  949.                                 sgw->NumChars = strlen( HAktu->ln_Name );
  950.                             }
  951.                             else
  952.                             {
  953.                                 sgw->WorkBuffer = "";
  954.                                 sgw->NumChars = 0;
  955.                                 HAktu = 0;
  956.                             }
  957.                             break;
  958.                     }
  959.                 }
  960.  
  961.                 if( sgw->Gadget == SearchWD.Gadgets[ GD_SEARCH_SEARCHSTRING ])
  962.                 {
  963.                     SHAktu = HAktu;
  964.                 }
  965.                 else
  966.                 {
  967.                     RHAktu = HAktu;
  968.                 }
  969.             }
  970.             else
  971.             {
  972.                     /* Prüfen, ob es sich um ein Gadget zur Hexzahleingabe handelt */
  973.  
  974.                 if( ((struct MyNewGadget *)sgw->Gadget->UserData)->Typ == HEX_KIND )
  975.                 {
  976.                     if( sgw->EditOp == EO_INSERTCHAR )
  977.                     {
  978.                         if( !isxdigit( sgw->Code ))
  979.                         {
  980.                             sgw->Actions = SGA_BEEP;
  981.                         }
  982.                     }
  983.                 }
  984.             }
  985.         }
  986.     }
  987.     else
  988.         return_code = 0;
  989.  
  990.    return(return_code);
  991. }
  992. struct Hook SearchHook =
  993. {
  994.     0, 0, (ULONG (*)()) SearchHookFunc, 0, 0
  995. };
  996.  
  997. BOOL OpenSearchWindow( BOOL ReplaceMode )
  998. {
  999.     ULONG err;
  1000.  
  1001.     if( SearchWD.Wnd )
  1002.     {
  1003.         ActivateWindow( SearchWD.Wnd );
  1004.         return( TRUE );
  1005.     }
  1006.  
  1007.     if( !IsListEmpty( &SHList ))
  1008.     {
  1009.          SearchNewGadgets[ GD_SEARCH_SEARCHSTRING ].CurrentValue = (LONG) SHList.lh_TailPred->ln_Name;
  1010.         SHAktu = SHList.lh_TailPred;
  1011.     }
  1012.     else
  1013.          SearchNewGadgets[ GD_SEARCH_SEARCHSTRING ].CurrentValue = (LONG) 0;
  1014.  
  1015.     if( !IsListEmpty( &RHList ))
  1016.     {
  1017.         SearchNewGadgets[ GD_SEARCH_REPLACESTRING ].CurrentValue = (LONG) RHList.lh_TailPred->ln_Name;
  1018.         RHAktu = RHList.lh_TailPred;
  1019.     }
  1020.     else
  1021.         SearchNewGadgets[ GD_SEARCH_REPLACESTRING ].CurrentValue = (LONG) 0;
  1022.  
  1023.     SearchNewGadgets[ GD_SEARCH_CASESENSITIV ].CurrentValue = ( searchmode & SM_CASE ) ? TRUE : FALSE;
  1024.     SearchNewGadgets[ GD_SEARCH_WILDCARDS ].CurrentValue    = ( searchmode & SM_WILDCARDS ) ? TRUE: FALSE;
  1025.     SearchNewGadgets[ GD_SEARCH_STRINGSEARCH ].CurrentValue = ( searchmode & SM_STRING ) ? TRUE: FALSE;
  1026.     SearchNewGadgets[ GD_SEARCH_REPLACEMODE ].CurrentValue = ReplaceMode;
  1027.     SearchNewGadgets[ GD_SEARCH_REPLACESTRING ].Disabled = !ReplaceMode;
  1028.  
  1029.     if( err =NewOpenAWindow( &SearchWD, GetStr( MSG_WINDOWTITLE_SEARCH )))
  1030.     {
  1031.         MyRequest( MSG_INFO_GLOBAL_CANTOPENWINDOW, err);
  1032.         return( FALSE );
  1033.     }
  1034.     else
  1035.     {
  1036.         ActivateGadget( SearchWD.Gadgets[ GD_SEARCH_SEARCHSTRING ], SearchWD.Wnd, 0 );
  1037.  
  1038.         MyAddSignal( 1L << SearchWD.Wnd->UserPort->mp_SigBit, &DoSearchWndMsg );
  1039.     }
  1040. }
  1041.